import { defineStore } from 'pinia'
import { store } from '@/stores'
import { cloneDeep } from 'lodash-es'
import { constantRoutes, dynamicRoutes } from '@/router/modules/remaining'
import { generateRoute } from '@/utils/routerHelper'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
import { hasAnyPermi, hasAnyRole } from '@/utils/perm'

const { wsCache } = useCache()

export interface PermissionState {
  routes: AppRouteRecordRaw[]
  addRoutes: AppRouteRecordRaw[]
  menuTabRoutes: AppRouteRecordRaw[]
}

export const usePermissionStore = defineStore('permission', {
  state: (): PermissionState => {
    return {
      routes: [], // 用于渲染菜单
      addRoutes: [], // 非remaining路由(用户的授权路由信息[导航目录、菜单])
      menuTabRoutes: []
    }
  },
  getters: {
    // 展示菜单
    getRoutes(): AppRouteRecordRaw[] {
      return this.routes
    },
    // 加入到router
    getAddRoutes(): AppRouteRecordRaw[] {
      return cloneDeep(this.addRoutes)
    },
    getMenuTabRoutes(): AppRouteRecordRaw[] {
      return this.menuTabRoutes
    }
  },
  actions: {
    async generateRoutes(): Promise<unknown> {
      return new Promise<void>(async (resolve) => {
        let res: AppCustomRouteRecordRaw[] = [] // 服务端返回用户菜单数据类型
        const roleRoutes = wsCache.get(CACHE_KEY.ROLE_ROUTES)
        if (roleRoutes) {
          res = roleRoutes as AppCustomRouteRecordRaw[]
        }
        const roleAppRoutes: AppRouteRecordRaw[] = generateRoute(res)
        this.addRoutes = roleAppRoutes.concat(filterPermedRoutes(dynamicRoutes))
        // vue-router@4以后已经支持静态404路由，写在remaining.ts中
        // this.addRoutes = roleAppRoutes.concat([
        //   {
        //     path: '/:path(.*)*',
        //     // redirect: '/404',
        //     component: () => import('@/views/base/error/404.vue'),
        //     name: '404Page',
        //     meta: {
        //       hidden: true,
        //       breadcrumb: false
        //     }
        //   }
        // ])
        // 深层拷贝，以免修改constantRoutes，用于渲染菜单(constant + serverSide)
        this.routes = cloneDeep(constantRoutes).concat(roleAppRoutes)
        resolve()
      })
    },
    setMenuTabRoutes(routes: AppRouteRecordRaw[]) {
      this.menuTabRoutes = routes
    }
  }
})

function filterPermedRoutes(routes: AppRouteRecordRaw[]) {
  const res: AppRouteRecordRaw[] = []
  routes.forEach((route) => {
    if (route.permissions?.length) {
      if (hasAnyPermi(route.permissions)) {
        if (!route.children?.length) {
          res.push(route)
        } else {
          const permedChildren = filterPermedRoutes(route.children)
          if (permedChildren?.length) {
            res.push({ ...route, children: permedChildren })
          }
        }
      }
    } else if (route.roles?.length) {
      if (hasAnyRole(route.roles)) {
        if (!route.children?.length) {
          res.push(route)
        } else {
          const permedChildren = filterPermedRoutes(route.children)
          if (permedChildren?.length) {
            res.push({ ...route, children: permedChildren })
          }
        }
      }
    } else {
      if (!route.children?.length) {
        res.push(route)
      } else {
        const permedChildren = filterPermedRoutes(route.children)
        if (permedChildren?.length) {
          res.push({ ...route, children: permedChildren })
        }
      }
    }
  })
  return res
}

export const usePermissionStoreWithOut = () => {
  return usePermissionStore(store)
}
